<template>
	<div>
		<el-dialog v-model="state.isShowDialog" width="769px" :before-close="onCancel">
			<template #header>
				<div style="color: #fff">
					<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
					<span>{{ props.title }}</span>
				</div>
			</template>
			<div class="cropper-warp">
				<div class="cropper-warp-left">
					<img :src="state.cropperImg" class="cropper-warp-left-img" />
				</div>
				<div class="cropper-warp-right">
					<div class="cropper-warp-right-title">预览</div>
					<div class="cropper-warp-right-item">
						<div class="cropper-warp-right-value">
							<img :src="state.cropperImgBase64" class="cropper-warp-right-value-img" />
						</div>
						<div class="cropper-warp-right-label">100 x 100</div>
					</div>
					<div class="cropper-warp-right-item">
						<div class="cropper-warp-right-value">
							<img :src="state.cropperImgBase64" class="cropper-warp-right-value-img cropper-size" />
						</div>
						<div class="cropper-warp-right-label">50 x 50</div>
					</div>
				</div>
			</div>
			<template #footer>
				<span class="dialog-footer">
					<el-upload
						ref="uploadSignRef"
						accept=".jpg,.png"
						:limit="1"
						:show-file-list="false"
						:auto-upload="false"
						:on-change="selectPicture"
						:on-exceed="selectPictureExceed"
						style="display: inline-block; position: absolute; right: 182px"
					>
						<el-button icon="ele-Picture">选择图片</el-button>
					</el-upload>
					<el-button @click="onCancel">取 消</el-button>
					<el-button type="primary" @click="onSubmit">确 定</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts" name="cropper">
import { reactive, nextTick, ref } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
import { genFileId } from 'element-plus';
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus';

const props = defineProps({
	title: {
		type: String,
		default: () => '',
	},
});
const emits = defineEmits(['uploadCropperImg']);
const uploadSignRef = ref<UploadInstance>();
// 定义变量内容
const state = reactive({
	isShowDialog: false,
	cropperImg: '',
	cropperImgBase64: '',
	cropper: '' as RefType,
});

// 打开弹窗
const openDialog = (imgs: string) => {
	state.cropperImg = imgs;
	state.isShowDialog = true;
	nextTick(() => {
		initCropper();
	});
};
// 关闭弹窗
const closeDialog = () => {
	state.cropper.destroy();
	state.isShowDialog = false;
};
// 取消
const onCancel = () => {
	closeDialog();
};
// 更换/上传
const onSubmit = async () => {
	const img = await getCroppedCanvas();
	emits('uploadCropperImg', { img: img });
	closeDialog();
};
// 初始化cropperjs图片裁剪
const initCropper = () => {
	const letImg = <HTMLImageElement>document.querySelector('.cropper-warp-left-img');
	if (letImg) {
		letImg.setAttribute('crossOrigin', 'anonymous');
	}
	state.cropper = new Cropper(letImg, {
		viewMode: 1,
		dragMode: 'none',
		initialAspectRatio: 1,
		aspectRatio: 1,
		preview: '.before',
		background: true,
		autoCropArea: 1,
		// zoomOnWheel: false,
		checkCrossOrigin: false,
		crop: () => {
			state.cropperImgBase64 = state.cropper.getCroppedCanvas()!.toDataURL('image/jpeg');
		},
	});
};

// 获取裁切后的图片 (包装为Promise)
const getCroppedCanvas = () => {
	return new Promise((resolve) => {
		state.cropper.getCroppedCanvas().toBlob((blob: any) => {
			resolve(blob);
		});
	});
};

// 选择图片
const selectPicture = async (file: any) => {
	let URL = window.URL || window.webkitURL;
	state.cropperImg = URL.createObjectURL(file.raw);
	state.cropper.replace(state.cropperImg);
};

// 选择图片超出数量限制时执行
const selectPictureExceed: UploadProps['onExceed'] = (files) => {
	uploadSignRef.value!.clearFiles();
	const file = files[0] as UploadRawFile;
	file.uid = genFileId();
	uploadSignRef.value!.handleStart(file);
};

// 暴露变量
defineExpose({
	openDialog,
});
</script>

<style scoped lang="scss">
.cropper-warp {
	display: flex;
	.cropper-warp-left {
		position: relative;
		display: inline-block;
		height: 350px;
		flex: 1;
		border: 1px solid var(--el-border-color);
		background: var(--el-color-white);
		overflow: hidden;
		background-repeat: no-repeat;
		cursor: move;
		border-radius: var(--el-border-radius-base);
		.cropper-warp-left-img {
			width: 100%;
			height: 100%;
		}
	}
	.cropper-warp-right {
		width: 150px;
		height: 350px;
		.cropper-warp-right-title {
			text-align: center;
			height: 20px;
			line-height: 20px;
		}
		.cropper-warp-right-item {
			margin: 15px 0;
			.cropper-warp-right-value {
				display: flex;
				.cropper-warp-right-value-img {
					width: 100px;
					height: 100px;
					border-radius: var(--el-border-radius-circle);
					margin: auto;
				}
				.cropper-size {
					width: 50px;
					height: 50px;
				}
			}
			.cropper-warp-right-label {
				text-align: center;
				font-size: 12px;
				color: var(--el-text-color-primary);
				height: 30px;
				line-height: 30px;
			}
		}
	}
}
</style>
